package com.atguigu.yygh.user.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.yygh.common.exception.YyghException;
import com.atguigu.yygh.common.utils.JwtHelper;
import com.atguigu.yygh.common.utils.R;
import com.atguigu.yygh.model.user.UserInfo;
import com.atguigu.yygh.user.properties.WxProperties;
import com.atguigu.yygh.user.service.UserInfoService;
import com.atguigu.yygh.user.utils.HttpClientUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Api(tags = "微信登录接口")
@Controller
@RequestMapping("/admin/user/wx")
@EnableConfigurationProperties(WxProperties.class)//启用属性类
public class WxController {

    @Autowired
    private WxProperties wxProperties;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserInfoService userInfoService;

    @ApiOperation("获取二维码信息")
    @ResponseBody
    @GetMapping("/getParams")
    public R getParams(HttpSession session) throws UnsupportedEncodingException {

        String state=System.currentTimeMillis()+session.getId();
        //使用urlEncode对链接进行转码
        String uri = wxProperties.getRedirectUri();
        String encode = URLEncoder.encode(uri, "UTF-8");

        //状态信息,存放到redis 有效期5分钟
        redisTemplate.opsForValue().set("state:"+state,"",5, TimeUnit.MINUTES);

        HashMap<String, Object> map = new HashMap<>();
        map.put("appid",wxProperties.getAppId());
        map.put("scope","snsapi_login");
        map.put("redirect_uri",encode);
        map.put("state",state);
        return R.ok().data(map);

    }

    @ApiOperation("微信回调的方法")

    @GetMapping("/callback")
    public String callback(String code,String state) throws Exception {

        //非空验证
        if (StringUtils.isEmpty(code)||StringUtils.isEmpty(state)){

            throw new YyghException(20001,"非法请求");
        }

        //验证状态信息,防止攻击
        Boolean hasKey = redisTemplate.hasKey("state:" + state);

        if (hasKey==null||!hasKey){

            throw new YyghException(20001,"状态异常");
        }

        //1.调用微信开放平台的接口  通过code 获取令牌
        String url1="https://api.weixin.qq.com/sns/oauth2/access_token?" +
                "appid=%s&secret=%s&code=%s&grant_type=authorization_code";
        url1=String.format(url1,wxProperties.getAppId(), wxProperties.getAppSecret(),code);
        //发送get请求
        String result1 = HttpClientUtils.get(url1);
        //将json 转换为对象
        JSONObject jsonObject1 = JSON.parseObject(result1);
        //access_token  接口调用凭证
        String access_token = jsonObject1.getString("access_token");
        //opeanid  授权用户唯一标识
        String openid = jsonObject1.getString("openid");
        //判断openid 是否存在(是否扫码登录注册过)
        QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<>();
        userInfoQueryWrapper.eq("openid",openid);

        UserInfo userInfo = userInfoService.getOne(userInfoQueryWrapper);



        if (userInfo==null){
            //不存在,第一次扫码
            //调用微信开放平台接口---获取个人信息
            String url2="https://api.weixin.qq.com/sns/userinfo?" +
                    "access_token=%s&openid=%s";
            url2=String.format(url2,access_token,openid);

            String result2 = HttpClientUtils.get(url2);

            JSONObject jsonObject2 = JSONObject.parseObject(result2);
            //nickname  普通用户昵称
            String nickname = jsonObject2.getString("nickname");

            //保存用户信息到数据库中
            userInfo = new UserInfo();
            userInfo.setOpenid(openid);
            userInfo.setNickName(nickname);
            userInfo.setStatus(1);
            userInfoService.save(userInfo);



        }

        //返回

        String name = userInfo.getName();
        if (StringUtils.isEmpty(name)){
            name=userInfo.getNickName();
        }
        if (StringUtils.isEmpty(name)){
            name=userInfo.getPhone();
        }

        Map<String, Object> map = new HashMap<>();
        map.put("name", URLEncoder.encode(name,"UTF-8"));
        map.put("token", JwtHelper.createToken(userInfo.getId(),name));
        //判断当前微信是否绑定了手机
        if(StringUtils.isEmpty(userInfo.getPhone())){
            //手机号为空,没绑定过,响应openid 给前端
            map.put("openid",openid);
        }else {
            map.put("openid","");
        }

        //重定向到首页
        String returnUrl="redirect:http://localhost:3000/weixin/callback?name=%s&token=%s&openid=%s";
        returnUrl=String.format(returnUrl,map.get("name"),map.get("token"),map.get("openid"));






        /*System.out.println("code = " + code);
        System.out.println("state = " + state);*/

        return returnUrl;
    }

}
